home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 014 (1988-05)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 014 (1988-05)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / FontConvert / convert.c < prev    next >
C/C++ Source or Header  |  1988-03-20  |  6KB  |  312 lines

  1. /*
  2.  * Macintosh font conversion program
  3.  * (C)1987 Rico Mariani
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <exec/types.h>
  8. #include <exec/nodes.h>
  9. #include <libraries/diskfont.h>
  10.  
  11. #define HUNK_HEADER  0x3f3
  12. #define HUNK_CODE    0x3e9
  13. #define HUNK_RELOC32 0x3ec
  14. #define HUNK_END     0x3f2
  15.  
  16. typedef struct {
  17.     UBYTE FontType;
  18.     UBYTE Padding;
  19.     UWORD FirstChar;
  20.     UWORD LastChar;
  21.     UWORD WidMax;
  22.     WORD  KernMax;
  23.     WORD  NDescent;
  24.     UWORD FRectWidth;
  25.     UWORD FRectHeight;
  26.     UWORD OWTLoc;
  27.     UWORD Ascent;
  28.     UWORD Descent;
  29.     UWORD Leading;
  30.     UWORD RowWords;
  31. } FHEADER;
  32.  
  33. unsigned char *BitImage;
  34. unsigned short LocTable[260];
  35. unsigned short OWTable[260];
  36. FILE *f;
  37.  
  38. char *rindex();
  39. void *malloc();
  40.  
  41. main(argc,argv)
  42. int argc;
  43. char *argv[];
  44. {
  45.     int i,j,c;
  46.     FHEADER h;
  47.     ULONG RowBytes;
  48.     ULONG num_chars, fontName, fontData, fontLoc, fontSpace;
  49.     ULONG fontKern, fontEnd, fontLength;
  50.     ULONG IStart, IEnd, CWidth, OW, Offset, Kern;
  51.     ULONG uc, lock;
  52.     char *s, buf[128];
  53.     WORD entries, size;
  54.     int padbytes;
  55.  
  56.     if(argc != 2) {
  57.         fprintf(stderr,"Usage: %s fontname\n",argv[0]);
  58.         exit(1);
  59.     }
  60.  
  61.     s = rindex(argv[1],'.');
  62.     if (!s) {
  63.         fprintf(stderr,"Error fontname must be of the form:\n");
  64.         fprintf(stderr,"\tname.pointsize\n");
  65.         exit(1);
  66.     }
  67.  
  68.     f = fopen(argv[1],"r");
  69.     if (!f){
  70.         fprintf(stderr,"Error can't open file '%s'\n",argv[1]);
  71.         exit(1);
  72.     }
  73.  
  74.  
  75.     fread( &h, sizeof(h), 1, f);
  76.  
  77.     printf("Font Data for %s:\n",argv[1]);
  78.     *s = '\0'; /* remove the suffix */
  79.     printf("\tChars %d to %d\n",h.FirstChar, h.LastChar);
  80.     printf("\tFont Rectangle (W,H) = (%d,%d)\n" ,
  81.         h.FRectWidth, h.FRectHeight);
  82.     printf("\tAscent = %d,  Descent = %d,  Leading = %d\n",
  83.         h.Ascent, h.Descent, h.Leading);
  84.  
  85.     RowBytes = 2*h.RowWords;
  86.  
  87.     BitImage = malloc(h.FRectHeight * RowBytes);
  88.     if (!BitImage) {
  89.         printf("Error, no memory for bit image\n");
  90.         exit(-1);
  91.     }
  92.  
  93.     fread(BitImage, h.FRectHeight * RowBytes, 1, f);
  94.  
  95.     for(i = h.FirstChar; i <= h.LastChar+2; i++) {
  96.         uc = fgetc(f);
  97.         LocTable[i] = uc << 8 | fgetc(f);
  98.     }
  99.  
  100.     for(i = h.FirstChar; i <= h.LastChar+2; i++) {
  101.         uc = fgetc(f);
  102.         OWTable[i] = uc << 8 | fgetc(f);
  103.     }
  104.  
  105.     fclose(f);
  106.  
  107.     sprintf(buf,"fonts:%s",argv[1]);
  108.     lock = CreateDir(buf);
  109.     if (lock) UnLock(lock);
  110.  
  111.     sprintf(buf,"fonts:%s/%d",argv[1],h.FRectHeight);
  112.     f = fopen(buf,"w");
  113.     if (!f) {
  114.         fprintf(stderr,"Error, can't open '%s' for write\n",buf);
  115.         exit(1);
  116.     }
  117.  
  118.     /* compute offsets into the code hunk */
  119.  
  120.     num_chars  = h.LastChar - h.FirstChar + 2;
  121.     fontName   = 0x1a;
  122.     fontData   = 0x6e;
  123.     fontLoc    = fontData  + RowBytes * h.FRectHeight;
  124.     fontSpace  = fontLoc   + (num_chars<<2);
  125.     fontKern   = fontSpace + (num_chars<<1);
  126.     fontEnd    = fontKern  + (num_chars<<1);
  127.  
  128.     /* long word align fontEnd */
  129.     padbytes = 0;
  130.     while (fontEnd & 3) {
  131.         padbytes++;
  132.         fontEnd++;
  133.     }
  134.     fontLength = fontEnd   - 0x3a;             /* the font: label */
  135.  
  136.  
  137.     outL(HUNK_HEADER);
  138.     outL(0);        /* no hunk names */
  139.     outL(1);        /* Size of hunk table */
  140.     outL(0);        /* First Hunk */
  141.     outL(0);        /* Last Hunk */
  142.     outL(fontEnd>>2);    /* Size of Hunk 0 */
  143.  
  144.     outL(HUNK_CODE);
  145.     outL(fontEnd>>2);    /* Size of this hunk */
  146.  
  147.     /* now here comes the data for the hunk */
  148.     /* this first part is in case someone tries to run this */
  149.  
  150.     outW(0x7000);        /* MOVEQ.L #0,D0 */
  151.     outW(0x4e75);        /* RTS */
  152.  
  153.     outL(0);        /* ln_Succ */
  154.     outL(0);        /* ln_Pred */
  155.     outB(NT_FONT);        /* ln_Type */
  156.     outB(0);        /* ln_Pri  */
  157.     outL(0x1a);        /* ln_Name -- will be relocated */
  158.     outW(DFH_ID);        /* FileID */
  159.     outW(1);        /* Revision */
  160.     outL(0);        /* Segment */
  161.  
  162. /* fontName: */
  163.  
  164.     outZ(MAXFONTNAME);    /* output 32 zeros */
  165.  
  166. /* font: */
  167.  
  168.     outL(0);        /* ln_Succ */
  169.     outL(0);        /* ln_Pred */
  170.     outB(NT_FONT);        /* ln_Type */
  171.     outB(0);        /* ln_Pri  */
  172.     outL(0x1a);        /* ln_Name -- will be relocated */
  173.     outL(0);        /* mn_ReplyPort */
  174.     outW(fontLength);    /* nm_Length */
  175.     outW(h.FRectHeight);    /* tf_YSize */
  176.     outB(0);        /* tf_Style */
  177.     outB(0x62);        /* tf_Flags */
  178.     outW(h.FRectWidth);    /* tf_XSize */
  179.     outW(h.Ascent);        /* ft_BaseLine */
  180.     outW(1);        /* tf_BoldSmear */
  181.     outW(0);        /* tf_Accessors */
  182.     outB(h.FirstChar);    /* tf_LoChar */
  183.     outB(h.LastChar);    /* tf_HiChar */
  184.     outL(fontData);        /* tf_CharData */
  185.     outW(RowBytes);        /* tf_Modulo */
  186.     outL(fontLoc);        /* tf_CharLoc */
  187.     outL(fontSpace);    /* tf_CharSpace */
  188.     outL(fontKern);        /* tf_CharKern */
  189.  
  190. /* fontData: */
  191.  
  192.     fwrite(BitImage, RowBytes * h.FRectHeight, 1, f);
  193.  
  194. /* fontLoc: */
  195.  
  196.     /* note that there is an extra character in every font on both  */
  197.     /* that Amiga and the Mac which is used when a character not in */
  198.     /* the font is requested */
  199.  
  200.     for (i=h.FirstChar; i<= h.LastChar + 1; i++) {
  201.         if (OWTable[i] == -1)
  202.             c = h.LastChar+1;
  203.         else
  204.             c = i;
  205.  
  206.         IStart = LocTable[c];
  207.         IEnd   = LocTable[c+1];
  208.         outW(IStart);
  209.         outW(IEnd-IStart);
  210.     }
  211.  
  212. /* fontSpace: */
  213.  
  214.     for (i=h.FirstChar; i<= h.LastChar+1; i++) {
  215.         OW = OWTable[i];
  216.         if (OWTable[i] == -1) OW = OWTable[h.LastChar+1];
  217.  
  218.         CWidth = OW & 0xff;
  219.         outW(CWidth);
  220.     }
  221.  
  222. /* fontKern: */
  223.  
  224.     for (i=h.FirstChar; i<= h.LastChar+1; i++) {
  225.         OW = OWTable[i];
  226.         if (OWTable[i] == -1) OW = OWTable[h.LastChar+1];
  227.  
  228.         Offset = OW >> 8;
  229.         Kern = h.KernMax + Offset;
  230.         outW(Kern);
  231.  
  232.     }
  233.  
  234.     for (i=0;i<padbytes;i++) outB(0);
  235.  
  236. /* fontEnd: */
  237.  
  238.     outL(HUNK_RELOC32);
  239.     outL(6);        /* of relocates number in this hunk */
  240.     outL(0);        /* hunk 0 */
  241.     outL(0x0e);        /* relocate reference to fontName: 1st */
  242.     outL(0x44);        /* relocate reference to fontName: 2nd */
  243.     outL(0x5c);        /* relocate reference to fontData:  */
  244.     outL(0x62);        /* relocate reference to fontLoc:   */
  245.     outL(0x66);        /* relocate reference to fontSpace: */
  246.     outL(0x6a);        /* relocate reference to fontKern:  */
  247.     outL(0);        /* zero to mark end */
  248.     outL(HUNK_END);
  249.  
  250.     fclose(f);
  251.  
  252.     sprintf(buf,"fonts:%s.font",argv[1]);
  253.     f = fopen(buf,"r+");
  254.     if (!f) {
  255.         f = fopen(buf,"w+");
  256.         if (!f) {
  257.             fprintf(stderr,"Error, can't create font header\n");
  258.             exit(1);
  259.         }
  260.         outW(0x0f00);    /* font header */
  261.         outW(0x0000);    /* number of font items */
  262.     }
  263.  
  264.     fseek(f,2,0);
  265.  
  266.     fread(&entries,2,1,f);
  267.  
  268.     for (i=0;i<entries;i++) {
  269.         fseek(f, 4+(260*i)+256, 0);
  270.         fread(&size,2,1,f);    /* read in ysize */
  271.         if (size == h.FRectHeight) {
  272.             printf("Amiga font of this size already exists");
  273.             printf("... overwritten\n");
  274.             exit(1);
  275.         }
  276.     }
  277.  
  278.     fseek(f,2,0);
  279.     outW(++entries);
  280.     fseek(f,0,2);
  281.     sprintf(buf,"%s/%d",argv[1],h.FRectHeight);
  282.     fwrite(buf,strlen(buf),1,f);
  283.     for (i=strlen(buf);i<256;i++) fputc(0,f);
  284.     outW(h.FRectHeight);
  285.     outB(0);
  286.     outB(0x62);
  287.     fclose(f);
  288. }
  289.  
  290. outB(b)
  291. {
  292.     fputc(b,f);
  293. }
  294.  
  295. outW(w)
  296. {
  297.     fputc(w>>8,f);
  298.     fputc(w&0xff,f);
  299. }
  300.  
  301. outL(l)
  302. {
  303.     fwrite(&l,4,1,f);
  304. }
  305.  
  306. outZ(n)
  307. {
  308.     int i;
  309.  
  310.     for (i=n;--i>=0;) fputc(0,f);
  311. }
  312.